import { BufferAttribute, BufferGeometry, Color, Mesh, Path, Points } from "three";
import { CustomPointsMaterial } from "../../../../renderExtension/Material/CustomMaterial";
import ShaderConst from "../../../../renderExtension/Material/ShaderConst";
import { App } from "../../../../application";
import Events from "../../../../application/constants/Events";

export default class FlowPoints extends Mesh {
    private app: App;
    
    public pointColor;
    public lineColor;
    private firstPoint;

    private points;
    private index = 0;
    // private num = 50;
    private pointsGeometry: BufferGeometry;
    private pointsMaterial: CustomPointsMaterial;
    private flyPoints: Points;
    private spaceDistance;
    private narrowLength = 50;
    private pointCount;
    private waitTime = 0;
    private pauseTime = 0;
    private isLoop = false;
    // private spaceInterval;
    // private pointNum;
    private updatePointsCallback;
    private updateSizeCallback;

    public constructor(pointColor: string, lineColor: string, firstPoint, points, spaceDistance, narrowLength, waitTime, isLoop) {
        super();
        // this.spaceInterval = spaceInterval;
        // this.pointNum = pointNum;
        
        this.app = App.getInstance();
        
        this.spaceDistance = spaceDistance;
        this.narrowLength = narrowLength;
        this.waitTime = waitTime;
        this.isLoop = isLoop;
        this.pointColor = pointColor;
        this.lineColor = lineColor;
        this.firstPoint = firstPoint;
        this.points = points;

        this.makePoints();

        this.updatePointsCallback = this.updatePoints.bind(this);
        this.app.on(Events.Render, this.updatePointsCallback);
        this.updateSizeCallback = this.updateSize.bind(this);
        this.app.on(Events.CameraChange, this.updateSizeCallback);
    }


    private makePoints() {
        this.pointsGeometry = new BufferGeometry();
        let points = this.updatePoints();

        // 每个顶点对应一个百分比数据attributes.percent 用于控制点的渲染大小
        var percentArr = []; //attributes.percent的数据
        for (var i = 0; i < points.length; i++) {
            percentArr.push(i / points.length);
            // percentArr.push(1);
        }
        var percentAttribue = new BufferAttribute(new Float32Array(percentArr), 1);
        this.pointsGeometry.attributes.percent = percentAttribue;
        // 批量计算所有顶点颜色数据
        var colorArr = [];
        for (var i = 0; i < points.length; i++) {
            var color1 = new Color(this.pointColor); //轨迹线颜色 青色
            var color2 = new Color(this.lineColor); //黄色
            var color = color1.lerp(color2, i / points.length)
            colorArr.push(color.r, color.g, color.b);
        }
        // 设置几何体顶点颜色数据
        this.pointsGeometry.attributes.color = new BufferAttribute(new Float32Array(colorArr), 3);

        let macrosList = new Array<string>();
        macrosList.push(ShaderConst.macrosConfig.flylineMacros);
        // 点模型渲染几何体每个顶点
        this.pointsMaterial = new CustomPointsMaterial({
            coreParameters: {
                // color: 0xffff00,
                // size: 5 * 5.0, //点大小
                vertexColors: true, //使用顶点颜色渲染
                transparent: true,//开启透明计算
                depthTest: false,
            }, macrosList: macrosList
        });
        this.updateSize();
        this.flyPoints = new Points(this.pointsGeometry, this.pointsMaterial);
        this.flyPoints.position.copy(this.firstPoint);
        //设置flyPoints的包围体，把包围球设置的比之前大100倍，避免点被裁剪
        this.flyPoints.geometry.computeBoundingSphere();
        this.flyPoints.geometry.boundingSphere.radius *= 100;
        this.renderOrder = 100;
        this.add(this.flyPoints);
    }

    private updatePoints() {
        if (this.index > (this.points.length - this.narrowLength) || this.index < 0) {
            this.index = 0;

            if(this.isLoop){
                this.parent?.remove(this);

                this.app.off(Events.Render, this.updatePointsCallback);
                this.app.off(Events.CameraChange, this.updateSizeCallback);
            }
        }

        var points2 = this.points.slice(this.index, this.index + this.narrowLength); //从曲线上获取一段
        var path = new Path();
        for (let i = 0; i < points2.length; i++) {
            let element = points2[i];
            if (i == 0) {
                path.moveTo(element.x, element.y);
            } else {
                path.lineTo(element.x, element.y);
                path.moveTo(element.x, element.y);
            }
        }

        this.pointCount = this.spaceDistance * this.narrowLength;
        let points = path.getSpacedPoints(this.pointCount);
        this.pointsGeometry.setFromPoints(points);

        this.pauseTime++;
        if(this.pauseTime >= this.waitTime){
            this.pauseTime = 0;
            this.index++;

           
        }

        // this.index++;
        return points;
    }

    
    private updateSize(){
        if(!this.pointsMaterial){
            return;
        }
        let cameraHeight = this.app.camera.position.z;
        this.pointsMaterial.size = 35000 / cameraHeight;
        this.pointsMaterial.sizeAttenuation = true;
        this.pointsMaterial.needsUpdate = true;
    }
}